﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Core.Interface;
using PServiceBus.Core.Runtime.Serializers;
using PServiceBus.Core.Runtime.Extensions;
using System.Collections;
using PServiceBus.Serializer.Xml;

namespace PServiceBus.Core.Runtime.Transformations {
    public class XmlTransformation : ITransformation {
        #region IDataTransformation Members

        public string Transform(Dictionary<string, object> param) {
            var xml = new StringBuilder();
            var keys = new string[param.Keys.Count];
            param.Keys.CopyTo(keys, 0);
            xml.Append("<Message>");

            //Use key copy to prevent collection modify exception
            for (var i = 0; i < keys.Length; i++) {
                var key = keys[i];
                var value = param[key];
                if (value == null) continue;
                var isString = value.GetType() == typeof(string);
                var valueText = isString ? value.ToString() : string.Empty;
                var isXmlBase64 = valueText.IsXmlBase64();
                value = isXmlBase64 ? valueText.XmlBase64ToXml() : value;
                xml.AppendFormat("<{0}>{1}</{0}>", key, value);
            }
            xml.Append("</Message>");

            return xml.ToString();
        }

        public string Transform(List<Dictionary<string, object>> list) {
            var xml = new StringBuilder();
            xml.Append("<List><Items type=\"Items\">");
            foreach (var param in list) xml.Append(Transform(param));
            xml.Append("</Items></List>");
            return xml.ToString();
        }

        public IEnumerable<TData> Transform<TData>(string data) where TData : class {
            return (XmlSerializer.Deserialize(data, this.GetGenericType<TData>()) as IList).Cast<TData>();
        }

        public Type GetCanonicalType(string data) {
            return this.ToCanonicalType((JsonSerializer.XmlToJson(data, includeDictTypeInfo: true).FromJson() as IList)[0] as Dictionary<string, object>);
        }
        #endregion
    }
}
